package com.rock.platform.core;


import java.sql.SQLException;

import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.TransactionRequiredException;

import org.hibernate.exception.SQLGrammarException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException;
import org.springframework.orm.jpa.JpaOptimisticLockingFailureException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;


@SuppressWarnings("serial")
public class DefaultJPAExceptionTranslatorDialect extends HibernateJpaDialect
{
    @Override
    public DataAccessException translateExceptionIfPossible(RuntimeException ex)
    {
        if (ex instanceof IllegalStateException) {
            return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
        }
        if (ex instanceof IllegalArgumentException) {
            return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
        }

        if (ex instanceof EntityNotFoundException) {
            return new JpaObjectRetrievalFailureException((EntityNotFoundException) ex);
        }
        if (ex instanceof NoResultException) {
            return new EmptyResultDataAccessException(ex.getMessage(), 1);
        }
        if (ex instanceof NonUniqueResultException) {
            return new IncorrectResultSizeDataAccessException(ex.getMessage(), 1);
        }
        if (ex instanceof OptimisticLockException) {
            return new JpaOptimisticLockingFailureException((OptimisticLockException) ex);
        }
        if (ex instanceof EntityExistsException) {
            if ( ex.getCause().getCause() instanceof SQLException )
            {
                return new DefaultJPADataAccessException(((SQLException)ex.getCause().getCause()).getMessage().trim(), (SQLException)ex.getCause().getCause()); 
            }
            else
            {
                return new JpaSystemException((PersistenceException) ex);
            }
        }
        if (ex instanceof TransactionRequiredException) {
            return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
        }

        if ( ex instanceof PersistenceException )
        {
            if ( ex.getCause() instanceof SQLGrammarException )
            {
                return new DefaultJPADataAccessException(((SQLGrammarException)ex.getCause()).getSQLException().getMessage().trim(), (SQLGrammarException)ex.getCause()); 
            }
            else
            {
                return new JpaSystemException((PersistenceException) ex);
            }
        }
        return null;
    }
}